package cn.tedu.sp11.filter;

import cn.tedu.web.util.JsonResult;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

//自定义的zuul过滤器 AccessFilter
//zuul会自动扫描这些Filter实例，并自动给它们配置好
@Component
public class AccessFilter extends ZuulFilter {

    //过滤器的类型（前置过滤器/后置.../路由.../错误处理...）前置最常用
    @Override
    public String filterType() {

        return FilterConstants.PRE_TYPE;  //过滤器常量.前置类型
        //return "pre";  //或者直接这么写也可以
    }

    //过滤器的顺序号（我自己的过滤器填加到前置过滤器们中的哪个位置）
    @Override
    public int filterOrder() {
        //为啥要放在第6个位置？
        //因为在zuul的默认过滤器的第5个过滤器中，向context对象身上添加了serviceId这个属性，所以在这个过滤器以后的过滤器才能访问到serviceid
        //这个AccessFilter过滤器顺序号要>5 ,才能得到serviceId（item-service，user-service，order-service）
        return FilterConstants.PRE_DECORATION_FILTER_ORDER+1; //PRE_DECORATION_FILTER_ORDER 的值就是5，也就是说明前5个过滤器位置已经固定被占了
        //return 6;  //或者直接这么写，放在第6位置
    }

    //针对当前这次请求，是否要执行过滤拦截代码（下面的run方法）？
    @Override
    public boolean shouldFilter() {
        //比如，我规定过滤掉那些想访问item-service的请求，就返回true。如果请求user-service和order-service，就不过滤，直接让它去访问

        //1.获取用户发送的请求的上下文对象RequestContext
        RequestContext ctx = RequestContext.getCurrentContext();

        //2.通过上下文对象获取到用户想要调用的服务的id（看他想访问谁）
        String serviceId = (String) ctx.get(FilterConstants.SERVICE_ID_KEY);

        //3.判断serviceId是否是item-service（并忽略大小写去比较）
        return "item-service".equalsIgnoreCase(serviceId);
    }

    //如果这个请求需要被过滤，就通过这个方法中的代码进行权限判断
    @Override
    public Object run() throws ZuulException {
        //看看没有token，如果有token，就表明这个用户已经登录了，就让他访问
        //如果没有token，就说明他还没有登录，不让他访问

        //通过上下文对象，获取request对象
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        //通过request对象获取token
        String token = request.getParameter("token");

        if(StringUtils.isBlank(token)){
            //1.如果没有检测到token，就阻止这个用户访问
            ctx.setSendZuulResponse(false);

            //2.向用户返回响应数据结果
            //数据结果的响应头
            ctx.addZuulResponseHeader("Content-Type","application/json;charset=utf-8");

            //状态：
            ctx.setResponseStatusCode(JsonResult.NOT_LOGIN); //其实就是400

            //数据结果的响应体
            ctx.setResponseBody(JsonResult.
                                          err().
                                          code(JsonResult.NOT_LOGIN).
                                          msg("还没登录呢吧？").toString());


        }
        //zuul的设计者的设计有问题（过度设计），到目前为止，还没用到这个返回值
        return null; //zuul的当前版本中，这个返回值没有使用，不发挥任何作用，这里返回任何内容都可以
    }
}
